package parser;

import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import net.htmlparser.jericho.Attribute;
import net.htmlparser.jericho.Attributes;
import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.HTMLElementName;
import net.htmlparser.jericho.Renderer;
import net.htmlparser.jericho.Source;
import sadxmlreader.TemplateStructure;

public class UrlWrapper {
	
	
	private UrlWrapper parentUrl;
	private List<UrlWrapper> childUrls;
	private Attribute att;
//	private String text;
	private StringBuilder text;
	private String urlBase;
	/**
	 * @return the att
	 */
	public Attribute getAtt() {
		return att;
	}
	/**
	 * @param att the att to set
	 */
	public void setAtt(Attribute att) {
		this.att = att;
		this.setText();	
		
	}
	private void setText() {
		URL url=null;
		try {
			String sectionUrl= this.att.getValue();
			
			url= new URL(getUrlBase()+sectionUrl);
			Source source=new Source(url);			
			Renderer renderBody = source.getRenderer();			
			this.text= new StringBuilder();			
			
			this.text.append(renderBody.toString());
			
		}
			catch (Exception e) {
				this.text.append("Sin Datos");
			}
		
	}
	public String getUrlBase() {
		
		return this.urlBase;
	}
	private String linkRaw;
	private boolean valid= false;
	public UrlWrapper(String urlBase) {
		this.urlBase= urlBase;
		childUrls = new ArrayList<UrlWrapper>();
		
	}
	/**
	 * @return the linkRaw
	 */
	public String getLinkRaw() {
		return linkRaw;
	}
	public UrlWrapper(){
		childUrls = new ArrayList<UrlWrapper>();
	}
	public UrlWrapper(Attribute attribute) {
		this.att= attribute;		
	}
	/**
	 * @return the parentUrl
	 */
	public UrlWrapper getParentUrl() {
		return parentUrl;
	}
	/**
	 * @param parentUrl the parentUrl to set
	 */
	public void setParentUrl(UrlWrapper parentUrl) {
		this.parentUrl = parentUrl;
	}
	/**
	 * @return the childUrls
	 */
	public List<UrlWrapper> getChildUrls() {
		return childUrls;
	}
	/**
	 * @param childUrls the childUrls to set
	 */
	public void setChildUrls(List<UrlWrapper> childUrls) {
		this.childUrls = childUrls;
	}
	
public UrlWrapper parse(Iterator<Element> elementos, Element elemento, Iterator<TemplateStructure> templateIter, TemplateStructure templateNode) throws Exception {
		
	
			UrlWrapper urlElement = null;	
			
				//VEr funcion de matching
				if(matching(elemento, templateNode)){
						urlElement = new UrlWrapper();
						urlElement.setValid();
						urlElement.setParentUrl(this);
						if(isLink(elemento)){					
							urlElement.setLink(getAttValue(elemento, "href"));							
							
						}else{
							
//							urlElement.setText(templateNode.getTitle());
						}
						//Es item
						if(elemento.getChildElements().size()==0 && templateNode.isItem()){						
								
							if(elementos.hasNext()){
								  childUrls.add(urlElement.parse(elementos, elementos.next(),templateIter,templateIter.next()));
								 
								}
							else{
								childUrls.add(urlElement);
								
						    }			
							
						}else{
							
							//Es seccion 	
							if(!templateNode.isItem()){
								//PAgina con hijos
								if(elemento.getChildElements().size()>0){
								
									Iterator<TemplateStructure> templateChild=  templateNode.getStrcture().iterator();
									Iterator<Element> subElement = elemento.getChildElements().iterator();
									//Agrego a estructura y y llamo con ambos hijos
									childUrls.add(urlElement.parse(subElement, subElement.next(),templateChild,templateChild.next()));
							
									
								}else{// tag sin hijos
									
									Iterator<TemplateStructure> templateChild=  templateNode.getStrcture().iterator();
									childUrls.add(urlElement.parse(elementos, elementos.next(),templateChild,templateChild.next()));
									
								}
							}							
							else
							{//Es un item 
								if(elementos.hasNext()){
									//Iterator<TemplateStructure> templateChild=  templateNode.getStrcture().iterator();
									Iterator<Element> subElement = elemento.getChildElements().iterator();
									//Agrego a estructura y y llamo con hijo de la pagina
									 childUrls.add(urlElement.parse(subElement, subElement.next(),templateIter,templateNode));
									// avanzo en ambas estructuras
									
									}
								else{
									
									childUrls.add(urlElement);
									
									
							    }
							
							}
									
						}					
					
						
				}else{// No hay matching
					
					 //tiene hijos el tag
					 if(elemento.getChildElements().size()>0){
							
						 Iterator<Element> subElement = elemento.getChildElements().iterator();
						 urlElement= parse(subElement, subElement.next(),templateIter,templateNode);
						 
					 }					
				
				}
				
				
				if(elementos.hasNext()){
					
					if(urlElement!=null && urlElement.isVAlid()){
						
						if(elementos.hasNext() && templateIter.hasNext()){
							urlElement= parse(elementos, elementos.next(),templateIter,templateIter.next()); 
						 }
						
						
					}else{
						
						urlElement= parse(elementos, elementos.next(),templateIter,templateNode);	
						
					}
					
							
				 }
				
				
				return urlElement;
		
			
}	

private boolean matching(Element elemento, TemplateStructure templateNode) {
	boolean rta=false;
	
		if(isLink(elemento)){
			
			rta=  elemento.getRenderer().toString().equals(templateNode.getTitle());
		}else{
			
			if(elemento.getChildElements().isEmpty()){
				rta=  elemento.getRenderer().toString().equals(templateNode.getTitle());
			}else
			{
				String todo = elemento.getTextExtractor().toString();
				String resto="";
				List <Element> hijos= elemento.getChildElements();
				for(int i=0;i<hijos.size();i++){
					if(!hijos.get(i).getTextExtractor().toString().isEmpty()){
						resto+=(hijos.get(i).getTextExtractor().toString());
						if(i<hijos.size()-1)
						resto+=" ";
					}
					
				}
				String resultado="";
				if(todo.length()> resto.length()){
				  resultado=todo.substring(0, todo.length()-resto.length()-1);
				}
				rta=resultado.equals(templateNode.getTitle());
			  
			  // (elemento.getBegin(), elemento.getChildElements().get(0).getBegin()).toString();
			}
//			elemento.subSequence(elemento.getBegin(),  elemento.getContent().getFirstStartTag().getBegin());
	       }
	
		return rta;
}
	


public void setLink(String attValue) {
	this.linkRaw=attValue;
	
}
private boolean typeA(Element elemento) {
	
	return elemento.getName().equals(HTMLElementName.A);
}

private boolean isLink(Element elemento) {
	
	boolean typeA= typeA(elemento);
		
	boolean hrefExist= !"".equals(getAttValue(elemento, "href"));
	return(typeA && hrefExist);
}

private String getAttValue(Element elemento,
		String key) {
	
	String rta="";
	Attributes att= elemento.getAttributes();
	boolean exist=false;
	 if(att!=null){
		 
	 Iterator<Attribute> atributos = att.iterator();
	 while (atributos.hasNext() && !exist) {
	 Attribute atributo = (Attribute) atributos.next();
	   if(atributo.getKey().equals(key))
		  exist= true;
	      rta= atributo.getValue();
	   }
	 }	
	return rta;
}
public void setValid() {
	valid=true;
	
}
public boolean isVAlid() {
	
	
	
	if (childUrls==null || childUrls.size()==0)
		return valid;
	for (int i = 0; i < childUrls.size(); i++) {
		if(!childUrls.get(i).isVAlid())
			return false;
	} 
	
	return true;
	
}
public void setValidAllChild() {
	
	for (int i = 0; i < childUrls.size(); i++) {
		UrlWrapper url = childUrls.get(i);
		url.setValid();
	}
	
}
public StringBuilder getText() {
	return text;
}
public void setText(StringBuilder text) {
	this.text = text;
}
public void addChild(UrlWrapper newElement) {
	childUrls.add(newElement);
	
}
public void setValid(boolean b) {
	this.valid=b;
	
}
public int getCantSections() {
	int cant=0;
	if(childUrls.size()>0){
		cant++;
		for (int i = 0; i < childUrls.size(); i++) {
			
			UrlWrapper wrapp= childUrls.get(i);
			cant+= wrapp.getCantSections();
			
		}
		
	}
	
	return cant;
}
public int getCantItems() {
	
	
	int cant=0;
	
	if(childUrls.isEmpty()){
		return 1;
	}else{
		if(childUrls.size()>0){
			
			for (int i = 0; i < childUrls.size(); i++) {
				
				UrlWrapper wrapp= childUrls.get(i);
				cant+= wrapp.getCantItems();
				
			}
			
	     }else
	     {
	    	 return 1;
	     }
	}
	
	return cant;
}
}
